package jpa.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;

import jpa.model.NotaFiscal;

import org.apache.log4j.Logger;

import jpa.factory.JPADAOFactory;

public class JPANotaFiscalDAO implements DAO<NotaFiscal> {

	private static Logger logger = Logger.getLogger(JPANotaFiscalDAO.class);
	
	private EntityManager manager;

	private EntityTransaction transaction;

	public JPANotaFiscalDAO () {
		manager = openPersistence();
	}
	
	

	public <T> void closePersistence(T persistence) {
		if (this.manager != null && this.manager.isOpen()) {
			this.manager.close();
		}
	}

	@SuppressWarnings("unchecked")
	public <T> T openPersistence() {
		if (this.manager == null) {
			this.manager = ((EntityManagerFactory) JPADAOFactory.getInstance()
					.getFactory()).createEntityManager();
		}
		return (T) this.manager;
	}

	public <T extends NotaFiscal> void atualizar(T notafiscal) {
		JPANotaFiscalDAO.logger.info("Atualizando a notafiscal: \n" + notafiscal);
		
		this.transaction = this.manager.getTransaction();
		
		if (notafiscal == null || notafiscal.getNotafiscal_id() == null) {
			throw new IllegalStateException("NotaFiscal Inválido");
		}
		try {
			this.transaction.begin();
			if (this.manager.contains(notafiscal)) {
				this.manager.merge(notafiscal);
			}
			this.manager.flush();
			this.transaction.commit();
		} catch (Exception e) {
			if (this.transaction.isActive())
				this.transaction.rollback();
			throw new IllegalStateException("Problema ao Persistir o Objeto");
		}
	}
	
	@SuppressWarnings("unchecked")
	public <T extends NotaFiscal> T recuperarPorId(Long id) {
		JPANotaFiscalDAO.logger.info("Recuperando a notafiscal por id: " + id);
		
		if (id == null || id <= 0) {
			throw new IllegalStateException("Identificador Inv�lido");
		}
		return (T) this.manager.find(NotaFiscal.class, id);
	}

	@SuppressWarnings("unchecked")
	public <T extends NotaFiscal> List<T> recuperarTodos() {
		JPANotaFiscalDAO.logger.info("Recuperando todas as notafiscals.");
		
		String consultaJPAQL = "select d from NotaFiscal d";
		Query query = manager.createQuery(consultaJPAQL);
		List<NotaFiscal> notafiscals = query.getResultList();
		return (List<T>) notafiscals;
	}

	@SuppressWarnings("unchecked")
	public <T extends NotaFiscal> T remover(Long id) {
		JPANotaFiscalDAO.logger.info("Removendo a notafiscal com id: " + id);
		
		this.transaction = this.manager.getTransaction();
		NotaFiscal notafiscal = this.recuperarPorId(id);
		if (notafiscal == null) {
			throw new IllegalStateException("NotaFiscal Inexistente para Remover");
		}
		try {
			this.transaction.begin();
			this.manager.remove(notafiscal);
			this.manager.flush();
			this.transaction.commit();
			return (T) notafiscal;
		} catch (Exception e) {
			if (this.transaction.isActive()){
				this.transaction.rollback();
			}
			throw new IllegalStateException("Problema ao Persistir o Objeto");
		}
	}

	public <T extends NotaFiscal> Long salvar(T notafiscal) {
		JPANotaFiscalDAO.logger.info("Salvando a notafiscal: \n" + notafiscal);
		
		this.transaction = this.manager.getTransaction();
		if (notafiscal == null) {
			throw new IllegalStateException("NotaFiscal Inv�lido");
		}
		try {
			this.transaction.begin();
			this.manager.persist(notafiscal);
			this.manager.flush();
			this.transaction.commit();
			return notafiscal.getNotafiscal_id().longValue();
		} catch (Exception e) {
			if (this.transaction.isActive()) {
				this.transaction.rollback();
			}
			e.printStackTrace();
			throw new IllegalStateException("Problema ao Persistir o Objeto");
		}
	}
}
